package com.eig.auth.config;

import com.alibaba.fastjson.JSON;
import com.eig.auth.service.MyUserService;
import com.eig.common.util.JWTUtil;
import com.eig.common.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.PrintWriter;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @program: eight-education-cloud
 * @description:
 * @author:
 **/
@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Autowired
    private MyUserService userService;
    //重写父类得两个方法。
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
          auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        //设置登录表单得规则
        http.formLogin()
                //如果登录成功执行得函数
                .successHandler(successHandler())
                //登录失败执行得函数
                .failureHandler(failureHandler())
                //放行
                .permitAll();
        //设置security允许登录跨域
        http.cors();
        //关闭跨域伪造请求.
        http.csrf().disable();
        //其他所有得请求都需要认证。
        http.authorizeRequests().anyRequest().authenticated();
    }

    //登录成功
    private AuthenticationSuccessHandler successHandler(){
         return (request, response, authentication) -> {
             response.setContentType("application/json;charset=utf-8");
             PrintWriter writer = response.getWriter();
             //生产token---userid+permission----JWT.
             //获取登录成功后用户对象。
             User user = (User) authentication.getPrincipal();
             //登录成功得账户
             String username = user.getUsername();
             //获取登录成功得账户具有得权限
             Collection<GrantedAuthority> authorities = user.getAuthorities();
             List<String> permissions=authorities.stream()
                                                 .filter(item->item.getAuthority()!=null)
                                                 .map(item->item.getAuthority()).collect(Collectors.toList());

             Map<String,Object> map=new HashMap<>();
             map.put("username",username);
             map.put("permissions",permissions);
             //按照账户和权限生产token
             String token = JWTUtil.createJWT(map);

             //封装到响应对象中
             Result result=new Result(2000,"登录成功",token);
             String jsonString = JSON.toJSONString(result);
             writer.print(jsonString);

             writer.flush();
             writer.close();
         };
    }

    //登录失败执行得方法
    private AuthenticationFailureHandler failureHandler() {
        return (request, response, e) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();

            Result result=new Result(5000,"账户或密码错误");
            String jsonString = JSON.toJSONString(result);
            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }
}








